package org.chinacloud.wanghui.jdownload;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Observable;

/**
 * Created with IntelliJ IDEA.
 * User: wanghui
 * Date: 13-10-29
 * Time: 下午11:49
 * To change this template use File | Settings | File Templates.
 */
public class Download extends Observable implements Runnable {
    private static final int MAX_BUFFER_SIZE = 1024;
    private static final String[] STATUSES = {"Downloading", "Paused", "Complete", "Cancelled", "Error"};


    private URL url;
    private int size;
    private int downloaded;
    private Status status;


    public Download(URL url) {
        this.url = url;
        size = -1;
        downloaded = 0;
        status = Status.DOWNLOADING;
        download();
    }




    public String getUrl() {
        return url.toString();
    }

    public int getSize() {
        return size;
    }

    public float getProgress() {
        return ((float) downloaded / size) * 100;
    }

    public Status getStatus() {
        return status;
    }

    public void pause() {
        status = Status.PAUSED;
        stateChanged();
    }

    public void resume() {
        status = Status.DOWNLOADING;
        stateChanged();
        download();
    }

    public void cancel() {
        status = Status.CANCELLED;
        stateChanged();
    }

    private void error() {
        status = Status.ERROR;
        stateChanged();
    }

    private void download() {
        Thread t = new Thread(this);
        t.start();
    }

    private String getFileName(URL url) {
        String fileName = url.getFile();
        return fileName.substring(fileName.lastIndexOf('/') + 1);
    }

    public void run() {
        RandomAccessFile file = null;
        InputStream stream = null;

        try {
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestProperty("Range", "bytes=" + downloaded + "-");

            conn.connect();

            int contentLength = conn.getContentLength();
            System.out.println(contentLength);
            if (conn.getResponseCode() / 100 != 2) {
                error();
            }


            if (contentLength < 1) {
                error();
            }

            if (size == -1) {
                size = contentLength;
                stateChanged();
            }

            file = new RandomAccessFile(getFileName(url), "rw");
            file.seek(downloaded);

            stream = conn.getInputStream();


            while (status == Status.DOWNLOADING) {
                byte[] buffer;
                System.out.println(size + "\t" + downloaded + "\t" +MAX_BUFFER_SIZE);
                if (size - downloaded > MAX_BUFFER_SIZE) {
                    buffer = new byte[MAX_BUFFER_SIZE];
                } else {
                    buffer = new byte[size - downloaded];
                }

                int read = stream.read(buffer);
                if (read == -1)
                    break;

                file.write(buffer, 0, read);
                downloaded += read;
                stateChanged();
            }
            if (status == Status.DOWNLOADING) {
                status = Status.COMPLETE;
                stateChanged();
            }


        } catch (Exception e) {
            error();
        } finally {
            if (file != null) {
                try {
                    file.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (stream != null) {
                try {
                    stream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private void stateChanged() {
        setChanged();
        notifyObservers();
    }


}
